package p.ithorns.sample.tracer.jaeger;

import com.alibaba.ttl.threadpool.TtlExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.concurrent.*;

/**
 * WebMvcConfig
 *
 * @author HtL
 * @date 2025/3/21 11:12
 * @since 1.0.0
 */
@Slf4j
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // registry.addInterceptor(new TraceInterceptor()).addPathPatterns("/**");
    }

    @Bean
    public FilterRegistrationBean<TraceFilter> filterRegistration() {
        return new FilterRegistrationBean<>(new TraceFilter()) {{
            addUrlPatterns("/*"); // 对所有URL生效
            setEnabled(true);
            setName("TraceFilter");
            setOrder(1); // 有多个Filter时，数字越小执行越早
        }};
    }

    /**
     * 使用阿里的 TransmittableThreadLocal 装饰线程池
     */
    @Bean("ttlExecutor")
    public Executor ttlExecutor() {
        ThreadFactory threadFactory = new ThreadFactoryBuilder().
                setUncaughtExceptionHandler(exceptionHandler).
                setNameFormat("ttl-%d").build();
        int processors = Runtime.getRuntime().availableProcessors();
        // log.info("processors:{}", processors);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1,
                processors * 2,
                0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingDeque<>(1000),
                threadFactory,
                new ThreadPoolExecutor.AbortPolicy());

        return TtlExecutors.getTtlExecutor(executor);
    }

    Thread.UncaughtExceptionHandler exceptionHandler = (Thread t, Throwable e) -> {
        log.info("current thread occurs error！", e);
    };

}